In [1]:
numbers = [1, 2, 3, 4]
squares = (n ** 2 for n in numbers)
In [2]:
1 in squares
Out[2]:
In [3]:
9 in squares
Out[3]:
In [4]:
4 in squares
Out[4]:
In [5]:
16 in squares
Out[5]:
In [6]:
numbers = [1, 2, 3, 4]
squares = (n ** 2 for n in numbers)
In [7]:
16 in squares
Out[7]:
In [8]:
1 in squares
Out[8]:
In [9]:
def uniques_only(iterable):
"""
Function that accepts an iterable and returns a new iterable
with all items from the original iterable except for duplicates.
"""
uniques = []
uniques_dict = {}
for item in iterable:
if item not in uniques_dict:
uniques_dict[item] = 1
uniques.append(item)
return uniques
In [10]:
uniques_only([1, 2, 2, 1, 1, 3, 2, 1])
Out[10]:
In [12]:
nums = [1, -3, 2, 3, -1]
squares = (n**2 for n in nums)
In [13]:
uniques_only(squares)
Out[13]:
In [15]:
def uniques_only(iterable):
"""
Function that accepts an iterable and returns a new iterable
with all items from the original iterable except for duplicates.
"""
uniques_dict = {}
for item in iterable:
if item not in uniques_dict:
uniques_dict[item] = 1
yield item
In [16]:
list(uniques_only([1, 2, 2, 1, 1, 3, 2, 1]))
Out[16]:
In [17]:
nums = [1, -3, 2, 3, -1]
squares = (n**2 for n in nums)
In [18]:
list(uniques_only(squares))
Out[18]:
In [19]:
uniques_only([1, 2, 2, 1, 1, 3, 2, 1])
Out[19]:
In [23]:
list(uniques_only({'a': 1, 'b':2, 'c': 3}))
Out[23]:
In [21]:
list(uniques_only([['a', 'b'], ['a', 'c'], ['a', 'b']]))
In [44]:
def uniques_only(iterable):
"""
Function that accepts an iterable and returns a new iterable
with all items from the original iterable except for duplicates.
"""
uniques_dict = {}
for item in iterable:
item = tuple(item)
if item not in uniques_dict:
uniques_dict[item] = 1
yield item
In [45]:
list(uniques_only([['a', 'b'], ['a', 'c'], ['a', 'b']]))
Out[45]:
In [46]:
list(uniques_only([1, 2, 2, 1, 1, 3, 2, 1]))
In [68]:
def uniques_only(iterable):
"""
Function that accepts an iterable and returns a new iterable
with all items from the original iterable except for duplicates.
"""
uniques_dict = {}
for item in iterable:
try:
hashed = tuple(item)
except TypeError:
hashed = item
if hashed not in uniques_dict:
uniques_dict[hashed] = 1
yield item
In [69]:
list(uniques_only([1, 2, 2, 1, 1, 3, 2, 1]))
Out[69]:
In [70]:
nums = [1, -3, 2, 3, -1]
squares = (n**2 for n in nums)
In [71]:
list(uniques_only(squares))
Out[71]:
In [72]:
list(uniques_only([['a', 'b'], ['a', 'c'], ['a', 'b']]))
Out[72]:
In [75]:
from timeit import default_timer
import unittest
class UniquesOnlyTests(unittest.TestCase):
"""Tests for uniques_only."""
def assertIterableEqual(self, iterable1, iterable2):
self.assertEqual(list(iterable1), list(iterable2))
def test_no_duplicates(self):
self.assertIterableEqual(uniques_only([1, 2, 3]), [1, 2, 3])
def test_adjacent_duplicates(self):
self.assertIterableEqual(uniques_only([1, 1, 2, 2, 3]), [1, 2, 3])
def test_non_adjacent_duplicates(self):
self.assertIterableEqual(uniques_only([1, 2, 3, 1, 2]), [1, 2, 3])
def test_lots_of_duplicates(self):
self.assertIterableEqual(uniques_only([1, 2, 2, 1, 1, 2, 1]), [1, 2])
def test_accepts_iterator(self):
nums = (n**2 for n in [1, 2, 3])
self.assertIterableEqual(uniques_only(nums), [1, 4, 9])
# To test the Bonus part of this exercise, comment out the following line
# @unittest.expectedFailure
def test_returns_iterator(self):
nums = iter([1, 2, 3])
output = uniques_only(nums)
self.assertEqual(iter(output), iter(output))
self.assertEqual(next(output), 1)
self.assertEqual(next(nums), 2)
# To test the Bonus part of this exercise, comment out the following line
# @unittest.expectedFailure
def test_accepts_nonhashable_types(self):
output = uniques_only([[1, 2], [3], [1], [3]])
self.assertIterableEqual(output, [[1, 2], [3], [1]])
# To test the Bonus part of this exercise, comment out the following line
# @unittest.expectedFailure
def test_hashable_types_faster(self):
hashables = [(n,) for n in range(4000)] + [0]
unhashables = [[n] for n in range(4000)] + [0]
with Timer() as hashable:
for _ in uniques_only(hashables):
pass
with Timer() as unhashable:
for _ in uniques_only(unhashables):
pass
self.assertLess(hashable.elapsed * 5, unhashable.elapsed)
class Timer:
"""Context manager to time a code block."""
def __enter__(self):
self.start = default_timer()
return self
def __exit__(self, *args):
self.end = default_timer()
self.elapsed = self.end - self.start
if __name__ == "__main__":
unittest.main(argv=['first-arg-is-ignored'], exit=False)
In [ ]: